{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n",
    "<dl class=\"dl-horizontal\">\n",
    "  <dt>Title</dt> <dd>DynamicMap Container</dd>\n",
    "  <dt>Dependencies</dt> <dd>Bokeh</dd>\n",
    "  <dt>Backends</dt> <dd><a href='./DynamicMap.ipynb'>Bokeh</a></dd> <dd><a href='../matplotlib/DynamicMap.ipynb'>Matplotlib</a></dd> <dd><a href='../plotly/DynamicMap.ipynb'>Plotly</a></dd>\n",
    "</dl>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import holoviews as hv\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A DynamicMap is an explorable multi-dimensional wrapper around a callable that returns HoloViews objects. A ``DynamicMap`` callable cannot return ``Layouts``, ``NdLayouts``, ``GridSpaces`` or other ``DynamicMaps`` or ``HoloMaps`` but can contain any other HoloViews object. See the [Building Composite Objects](../../../user_guide/06-Building_Composite_Objects.ipynb) user guide for details on how to compose containers and for the user-guide describing ``DynamicMap`` in more detail, see the [Live Data](../../../user_guide/07-Live_Data.ipynb) user guide.\n",
    "\n",
    "\n",
    "<p><center><div class=\"alert alert-info\" role=\"alert\"><b>Note: </b>To work with live data, you need a live Python server, not a static web site, which is why the outputs shown below are GIF animations. If you run this notebook yourself, you will be able to try out your own interactions and compare them to the displayed GIF animations.</div></center></p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ``DynamicMap`` holds callables"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Although a ``DynamicMap`` holds a user supplied callable, this can be seen as as a generalization of [``HoloMap``](./HoloMap.ipynb) which holds dictionaries of elements: the key is then conceptually the arguments to the callable and the value is the object the callable returns. This conceptual model assume the callable is a true function where a set of arguments always maps to the same output, no matter how many times it is called.\n",
    "\n",
    "For [``HoloMap``](./HoloMap.ipynb), we used the ``sine_curve`` function below to generate a dictionary of ``Curve`` objects. With ``DynamicMap``, we can use it directly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "frequencies = [0.5, 0.75, 1.0, 1.25]\n",
    "\n",
    "def sine_curve(phase, freq):\n",
    "    xvals = [0.1* i for i in range(100)]\n",
    "    return hv.Curve((xvals, [np.sin(phase+freq*x) for x in xvals]))\n",
    "\n",
    "# When run live, this cell's output should match the behavior of the GIF below\n",
    "dmap = hv.DynamicMap(sine_curve, kdims=['phase', 'frequency'])\n",
    "dmap.redim.range(phase=(0.5,1), frequency=(0.5,1.25))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src='https://s3-eu-west-1.amazonaws.com/assets.holoviews.org/gifs/examples/containers/bokeh/DynamicMap.gif'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Unlike a ``HoloMap`` which is limited by the static number of items in the supplied dictionary (which must all exist in memory at once), this ``DynamicMap`` lets you pick any phase or frequency within the supplied range.\n",
    "\n",
    "Although ``DynamicMap`` is designed as the dynamic counterpart of [``HoloMap``](./HoloMap.ipynb), the fact that it accepts a code specification as opposed to data opens up a large set of new possibilities. The [Live Data](../../../user_guide/07-Live_Data.ipynb)  user guide is dedicated to exploring what can be done with ``DynamicMap``."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
